package com.dingreading.cloud.admin.controller;

import com.alibaba.excel.EasyExcel;
import com.dingreading.cloud.admin.dto.BookLabelDto;
import com.dingreading.cloud.admin.dto.BooksDto;
import com.dingreading.cloud.admin.dto.vo.BookLabelVO;
import com.dingreading.cloud.admin.dto.vo.BooksVO;
import com.dingreading.cloud.admin.entity.Books;
import com.dingreading.cloud.admin.entity.StoreBooks;
import com.dingreading.cloud.admin.entity.Stores;
import com.dingreading.cloud.admin.mapper.StoresMapper;
import com.dingreading.cloud.admin.service.BooksService;
import com.dingreading.cloud.admin.service.StoreBooksService;
import com.dingreading.cloud.admin.util.bean.BookImportUtil;
import com.dingreading.cloud.admin.util.bean.BooksUtil;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.dto.AliyunBookDto;
import com.dingreading.cloud.common.util.DateUtil;
import com.dingreading.cloud.common.util.DescribeException;
import com.dingreading.cloud.common.util.PageBeanDto;
import com.dingreading.cloud.common.util.PageUtil;
import com.dingreading.cloud.common.util.aliyun.AliyunBookUtil;
import com.dingreading.cloud.common.util.excel.ExcelHandler;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/books")
@Api(tags = "总部-书籍管理")
public class BooksController {

    @Resource
    private StoresMapper storesMapper;
    @Resource
    private BooksService booksService;
    @Resource
    private StoreBooksService storeBooksService;
    @Resource
    private BookImportUtil bookImportUtil;


    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList")
    public R<Object> pageList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "书名/书号/作者/出版社") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "启用状态 -1.下架 1.上架") @RequestParam(value = "status", required = false) Integer status
    ) {
        Page<Books> page = booksService.pageList(pageUtil, keyword, status);
        PageBeanDto data = new PageBeanDto();
        data.setTotal(page.getTotalRow());
        data.setList(page.getRecords());
        return R.ok(data);
    }

    @Transactional(rollbackFor = DescribeException.class)
    @Deprecated
    @ApiOperation(value = "添加/编辑总部书籍信息")
    @PostMapping(value = "/editBooks", produces = "application/json; charset=UTF-8")
    public R<Object> editBooks(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "分类id") @RequestParam(value = "bookLabelId", required = false) Long bookLabelId,
            @ApiParam(value = "分类") @RequestParam(value = "bookLabelName", required = false) String bookLabelName,
            @ApiParam(value = "总部书籍id") @RequestParam(value = "booksId", required = false) Long booksId,
            @ApiParam(value = "书号") @RequestParam(value = "isbn", required = false) String isbn,
            @ApiParam(value = "书名") @RequestParam(value = "bookName", required = false) String bookName,
            @ApiParam(value = "封面") @RequestParam(value = "img", required = false) String img,
            @ApiParam(value = "作者") @RequestParam(value = "author", required = false) String author,
            @ApiParam(value = "出版社") @RequestParam(value = "press", required = false) String press,
            @ApiParam(value = "出版日期") @RequestParam(value = "pubDate", required = false) String pubDate,
            @ApiParam(value = "简介") @RequestParam(value = "synopsis", required = false) String synopsis,
            @ApiParam(value = "介绍") @RequestParam(value = "introduction", required = false) String introduction,
            @ApiParam(value = "单价") @RequestParam(value = "unitPrice", required = false) Double unitPrice,
            @ApiParam(value = "库存") @RequestParam(value = "stockCount", required = false) Integer stockCount,
            @ApiParam(value = "可借数量") @RequestParam(value = "borrowCount", required = false) Integer borrowCount,
            @ApiParam(value = "状态：-1.下架 1.上架") @RequestParam(value = "status", required = false) Integer status
    ) throws Exception {
        Books books = null;
        if (id == null || id <= 0) {
            // 新增
            // 获取书号
            Books maxBooks = booksService.getMaxBookNum();
            String bookNum = null;
            try {
                bookNum = BooksUtil.getBookNum(maxBooks);
            } catch (Exception e) {
                throw new DescribeException(4005, "获取获取最新书号错误");
            }
            // 新增
            books.setBookNum(bookNum);
            books.setBookLabelId(bookLabelId);
            books.setBookLabelName(bookLabelName);
            books.setIsbn(isbn);
            books.setBookName(bookName);
            books.setImg(img);
            books.setAuthor(author);
            books.setPress(press);
            books.setPubDate(pubDate);
            books.setSynopsis(synopsis);
            books.setIntroduction(introduction);
            books.setUnitPrice(unitPrice);
            books.setStatus(1);
            books.setSource(1);
            booksService.saveOrUpdate(books);
            // 同步新增书籍到门店
            addStoreBooks(books);
        } else {
            // 修改
            books = booksService.getById(id);
            if (books == null)
                return R.fail("书籍获取失败");

            books.setBookLabelId(bookLabelId);
            books.setBookLabelName(bookLabelName);
            books.setIsbn(isbn);
            books.setBookName(bookName);
            books.setImg(img);
            books.setAuthor(author);
            books.setPress(press);
            books.setPubDate(pubDate);
            books.setSynopsis(synopsis);
            books.setIntroduction(introduction);
            books.setUnitPrice(unitPrice);
            books.setStatus(status);
            booksService.saveOrUpdate(books);
            // 修改门店书籍信息
            List<StoreBooks> storeBooksList = storeBooksService.getByBooksId(books.getId());
            if (CollectionUtils.isNotEmpty(storeBooksList)) {
                for (StoreBooks storeBooks : storeBooksList) {
                    storeBooks.setIsbn(books.getIsbn());
                    storeBooks.setBookName(books.getBookName());
                    storeBooks.setImg(books.getImg());
                    storeBooks.setAuthor(books.getAuthor());
                    storeBooks.setPress(books.getPress());
                    storeBooks.setPubDate(books.getPubDate());
                    storeBooks.setSynopsis(books.getSynopsis());
                    storeBooks.setIntroduction(books.getIntroduction());
                    storeBooks.setUnitPrice(books.getUnitPrice());
                    storeBooks.setBookLabelId(books.getBookLabelId());
                    storeBooks.setBookLabelName(books.getBookLabelName());
                    storeBooks.setBookTypeId(books.getBookTypeId());
                    storeBooks.setBookType(books.getBookType());
                    storeBooks.setJournalId(books.getJournalId());
                    storeBooks.setJournalName(books.getJournalName());
                    storeBooks.setJournalNum(books.getJournalNum());
                }
                storeBooksService.saveOrUpdateBatch(storeBooksList);
            }
        }
        return R.ok();
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "添加/编辑总部书籍信息")
    @PostMapping(value = "/newBean", produces = "application/json; charset=UTF-8")
    public R<Object> newBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "书籍id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "书名") @RequestParam(value = "bookName") String bookName,
            @ApiParam(value = "书号") @RequestParam(value = "isbn") String isbn,
            @ApiParam(value = "作者") @RequestParam(value = "author", required = false) String author,
            @ApiParam(value = "价格") @RequestParam(value = "unitPrice", required = false) Double unitPrice,
            @ApiParam(value = "出版社") @RequestParam(value = "press", required = false) String press,
            @ApiParam(value = "出版日期") @RequestParam(value = "pubDate", required = false) String pubDate,
            @ApiParam(value = "封面图") @RequestParam(value = "img", required = false) String img,
            @ApiParam(value = "字数") @RequestParam(value = "wordCount", required = false) Double wordCount,
            @ApiParam(value = "简介") @RequestParam(value = "synopsis", required = false) String synopsis,
            @ApiParam(value = "介绍") @RequestParam(value = "introduction", required = false) String introduction,
            @ApiParam(value = "分类id") @RequestParam(value = "bookLabelId", required = false) Long bookLabelId,
            @ApiParam(value = "分类名称") @RequestParam(value = "bookLabelName", required = false) String bookLabelName
    ) throws Exception {
        if (id == null || id <= 0) {
            // 新增
            // 获取书号
            Books maxBooks = booksService.getMaxBookNum();
            String bookNum = null;
            try {
                bookNum = BooksUtil.getBookNum(maxBooks);
            } catch (Exception e) {
                throw new DescribeException(4005, "获取最新书号错误");
            }
            Books books = new Books();
            books = BooksUtil.editBookInfo(
                    books, bookName, isbn, author, unitPrice, press, pubDate, img, wordCount, synopsis,
                    introduction, bookLabelId, bookLabelName
            );
            books.setBookNum(bookNum);
            books.setStatus(1);
            books.setSource(1);
            booksService.saveOrUpdate(books);
        } else {
            // 修改
            Books books = booksService.getById(id);
            if (null == books)
                return R.fail("书籍获取失败");

            books = BooksUtil.editBookInfo(
                    books, bookName, isbn, author, unitPrice, press, pubDate, img, wordCount, synopsis, introduction,
                    bookLabelId, bookLabelName
            );
            booksService.saveOrUpdate(books);
            // 修改关联的门店书籍信息
            List<StoreBooks> storeBooksList = storeBooksService.getByBooksId(id);
            if (CollectionUtils.isNotEmpty(storeBooksList)) {
                for (StoreBooks storeBooks : storeBooksList) {
                    storeBooks.setIsbn(books.getIsbn());
                    storeBooks.setBookName(books.getBookName());
                    storeBooks.setImg(books.getImg());
                    storeBooks.setAuthor(books.getAuthor());
                    storeBooks.setPress(books.getPress());
                    storeBooks.setPubDate(books.getPubDate());
                    storeBooks.setSynopsis(books.getSynopsis());
                    storeBooks.setIntroduction(books.getIntroduction());
                    storeBooks.setUnitPrice(books.getUnitPrice());
                    storeBooks.setBookLabelId(books.getBookLabelId());
                    storeBooks.setBookLabelName(books.getBookLabelName());
                }
                storeBooksService.saveOrUpdateBatch(storeBooksList);
            }
        }
        return R.ok();
    }

    @ApiOperation(value = "根据书刊id获取")
    @PostMapping(value = "/getByJournalId", produces = "application/json; charset=UTF-8")
    public R<Object> getByJournalId(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "书刊id") @RequestParam(value = "journalId") Long journalId
    ) {
        List<Books> booksList = booksService.getByJournalIdOrderByAddTimeAsc(journalId);
        return R.ok(booksList);
    }

    @ApiOperation(value = "根据id获取信息")
    @PostMapping(value = "/getById", produces = "application/json; charset=UTF-8")
    public R<Object> getById(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id
    ) {
        Books books = booksService.getById(id);
        return R.ok(books);
    }

    @ApiOperation(value = "删除书籍")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id
    ) {
        long l = booksService.dropBean(id);
        if (l <= 0) return R.failDel();
        return R.ok();
    }


    @ApiOperation(value = "更新状态")
    @PostMapping(value = "/updateStatus", produces = "application/json; charset=UTF-8")
    public R<Object> updateStatus(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "状态：-1.下架 1.上架") @RequestParam(value = "status") Integer status
    ) {
        long l = booksService.updateStatus(id, status);
        if (l <= 0) return R.fail("更新状态失败");
        return R.ok();
    }


    @ApiOperation(value = "搜索书籍")
    @PostMapping(value = "/search", produces = "application/json; charset=UTF-8")
    public R<List<Books>> search(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "关键字") @RequestParam(value = "keyword", required = false) String keyword
    ) {
        List<Books> booksList;
        if (StringUtils.isNotBlank(keyword)) {
            booksList = this.booksService.searchByKeyword(keyword);
        } else {
            booksList = this.booksService.getByStatus(1);
        }
        return R.ok(booksList);
    }

    /**
     * 总部新增书籍时同步门店书籍
     *
     * @param books 书籍
     */
    private void addStoreBooks(Books books) {
        // 获取所有门店
        List<Stores> shopList = storesMapper.selectAll();
        // 同步书籍
        List<StoreBooks> storeBooksList = new ArrayList<>();
        Date time = DateUtil.getNowDatetime();
        for (int i = 0; i < shopList.size(); i++) {
            StoreBooks storeBooks = BooksUtil.newStoreBooks(books, shopList.get(i).getId(), time, 1);
            storeBooksList.add(storeBooks);
            // 保存
            if (storeBooksList.size() >= 1000 || i == shopList.size() - 1) {
                storeBooksService.saveOrUpdateBatch(storeBooksList);
                storeBooksList = new ArrayList<>();
            }
        }
    }

    @ApiOperation(value = "导入书籍前判断是否已存在")
    @PostMapping(value = "/judgeHaveBook")
    public R<Object> judgeHaveBook(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "书籍数据excel") @RequestPart(value = "books") MultipartFile multipartFile
    ) throws Exception {
        List<BooksVO> voList = ExcelHandler.importExcel(multipartFile, BooksVO.class, null);
        if (CollectionUtils.isEmpty(voList)) return R.fail("导入的书籍数据为空");

        if (CollectionUtils.isNotEmpty(voList)) {
            List<String> strings = voList.stream().map(BooksVO::getIsbn).collect(Collectors.toList());
            List<BooksDto> list = booksService.getByIsbns(strings);
            return R.fail(4001, "发现部分书籍已导入", list);
        }
        return R.ok();
    }

    @ApiOperation(value = "导入总部书籍")
    @PostMapping(value = "/importBook")
    @ApiImplicitParam(name = "importBook", value = "storeIds", allowMultiple = true, dataTypeClass = List.class, paramType = "query")
    public R<Object> importBook(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "书籍数据excel") @RequestPart(value = "books") MultipartFile multipartFile,
            @ApiParam(value = "门店id集合") @RequestParam(value = "storeIds", required = false) List<Long> storeIds
    ) throws Exception {
        List<BooksVO> voList = ExcelHandler.importExcel(multipartFile, BooksVO.class, null);
        if (CollectionUtils.isEmpty(voList)) return R.fail("导入的书籍数据为空");

        List<Books> newList = new ArrayList<>();
        Map<String, Integer> numMap = new HashMap<>();
        Date time = DateUtil.getNowDatetime();
        // 添加书籍信息
        for (int i = 0; i < voList.size(); i++) {
            BooksVO booksVO = voList.get(i);
            // 书名
            String bookName = booksVO.getBookName();
            if (StringUtils.isBlank(bookName)) return R.fail("填写书名, 第" + (i + 1) + "行");
            if (bookName.length() > 255) return R.fail("书名长度超过限制, 第" + (i + 1) + "行");
            // isbn
            String isbn = booksVO.getIsbn();
            if (StringUtils.isBlank(isbn)) return R.fail("填写书号, 第" + (i + 1) + "行");
            // 作者
            String author = booksVO.getAuthor();
            // 分类
            String labelName = booksVO.getBookLabel();
            // 出版社
            String press = booksVO.getPress();
            // 出版日期
            String pubDate = booksVO.getPubDate();
            // 价格
            Double price = booksVO.getPrice();
            // 数量
            Integer nums = booksVO.getNums();
            // 简介
            String synopsis = booksVO.getSynopsis();

            // 创建门店书籍实体
            Books data = new Books();
            data.setBookName(bookName);
            data.setBookLabelName(labelName);
            data.setIsbn(isbn);
            if (StringUtils.isNotBlank(author))
                data.setAuthor(author);
            if (StringUtils.isNotBlank(press))
                data.setPress(press);
            if (StringUtils.isNotBlank(pubDate))
                data.setPubDate(AliyunBookUtil.pubDateToYmd(pubDate));
            if (null != price)
                data.setUnitPrice(price);
            if (StringUtils.isNotBlank(synopsis)) {
                data.setSynopsis(synopsis);
            }
            data.setStatus(1);
            data.setSource(1);
            data.setAddTime(time);
            data.setEditTime(time);

            numMap.put(isbn, nums);
            newList.add(data);
        }

        // 异步添加书籍信息
        bookImportUtil.insertBook(newList, numMap, storeIds, time);

        return R.fail(0, "保存书籍数量：" + newList.size() + "，正在保存请稍后查询.");
    }


    @ApiOperation(value = "更新没有封面图的书籍")
    @PostMapping(value = "/updateBookImg", produces = "application/json; charset=UTF-8")
    public R<Object> updateBookImg(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil
    ) {
        Page<Books> page = booksService.getNotImg(pageUtil);
        List<Books> booksList = page.getRecords();
        if (CollectionUtils.isNotEmpty(booksList)) {
            Date time = DateUtil.getNowDatetime();

            LinkedHashMap<String, List<Books>> map = booksList.stream()
                    .collect(Collectors.groupingBy(Books::getIsbn, LinkedHashMap::new, Collectors.toList()));
            for (Map.Entry<String, List<Books>> entry : map.entrySet()) {
                String isbn = entry.getKey();
//                System.out.println("序号 = " + i++);
//                System.out.println("isbn = " + isbn);
                List<Books> value = entry.getValue();
                if (StringUtils.isNotBlank(isbn)) {
                    List<Long> ids = value.stream().map(Books::getId).collect(Collectors.toList());
                    R<AliyunBookDto.ResultDTO> R = AliyunBookUtil.getBook(isbn);
                    if (R.getSt() == 0) {
                        AliyunBookDto.ResultDTO data = R.getData();
                        if (StringUtils.isNotBlank(data.getPic())) {
                            long l = booksService.updateImg(ids, data.getPic(), time);
                            if (l > 0)
                                System.out.println("更新图片成功，书籍id= " + ids);
                        } else {
                            long l = booksService.updateImg(ids, "", time);
                            if (l > 0)
                                System.out.println("没有图片，更新时间成功，书籍id= " + ids);
                        }
                    } else {
                        long l = booksService.updateImg(ids, "", time);
                        if (l > 0)
                            System.out.println("没有查到，更新时间成功，书籍id= " + ids);
                    }
                }
            }
        }

        return R.ok();
    }

//    
//    @ApiOperation(value = "下载随机数量的书籍封面")
//    @PostMapping(value = "/downloadImages", produces = "application/json; charset=UTF-8")
//    public void downloadImages(
//            HttpServletRequest request,
//            HttpServletResponse response,
//            @ApiParam(value = "下载封面数量") @RequestParam(value = "num") Integer num
//    ) throws Exception {
//        // 获取随机数量的jisu图片
//        List<String> images = booksService.getRandomImages(num, "%api.jisuapi.com%");
//
//        if (CollectionUtils.isEmpty(images))
//            throw new DescribeException("书籍封面获取失败");
//        FileUtil.batchDownloadFile(images, request, response);
//    }

//    @ApiOperation(value = "导入补充出版日期")
//    @PostMapping(value = "/importPubDate", produces = "application/json; charset=UTF-8")
//    public R<Object> importPubDate(
//            @ApiParam(value = "书籍数据excel") @RequestPart(value = "books") MultipartFile multipartFile
//    ) throws Exception {
//        
//
//        List<PubDateVO> voList = excelHandler.importExcel(multipartFile, PubDateVO.class, null);
//        if (CollectionUtils.isEmpty(voList))
//            return R.fail("导入的数据为空");
//
//        Map<String, List<String>> map = voList.stream()
//                .filter(vo -> StringUtils.isNotBlank(vo.getIsbn()) && StringUtils.isNotBlank(vo.getPubDate()) && !vo.getPubDate().equals("-"))
//                .collect(Collectors.groupingBy(PubDateVO::getPubDate, Collectors.mapping(PubDateVO::getIsbn, Collectors.toList())));
//
//        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
//            String pubDate = entry.getKey();
//            List<String> isbnList = entry.getValue();
//
//            booksService.updatePubDate(isbnList, pubDate);
//        }
//
//        return R.ok();
//    }

//    @ApiOperation(value = "阿里云查询补充出版日期")
//    @PostMapping(value = "/aliyunPubDate", produces = "application/json; charset=UTF-8")
//    public R<Object> aliyunPubDate() throws Exception {
//        
//
//        List<String> isbnList = booksService.getIsbnByPubDateIsNull();
//
//        if (CollectionUtils.isEmpty(isbnList))
//            return R.fail("未查询到需要补充出版日期的书号");
//
//        for (String isbn : isbnList) {
//            result = AliyunBookUtil.getBook(isbn);
//            if (result.getSt() != 0) {
//                System.out.println("未查询到书籍信息isbn：" + isbn);
//            } else {
//                AliyunBookDto.ResultDTO resultDto = (AliyunBookDto.ResultDTO) result.getData();
//                if (resultDto != null) {
//                    String pubDate = resultDto.getPubdate();
//                    if (StringUtils.isNotBlank(pubDate)) {
//                        booksService.updatePubDate(Collections.singletonList(isbn), pubDate);
//                    }
//                }
//            }
//        }
//        return R.ok();
//    }

    @ApiOperation(value = "给书单补充分类")
    @PostMapping(value = "/makeupLabel", produces = "application/json; charset=UTF-8")
    public void makeupLabel(
            HttpServletRequest request,
            HttpServletResponse response,
            @ApiParam(value = "书籍分类数据excel") @RequestPart(value = "books") MultipartFile multipartFile
    ) throws Exception {
        List<BookLabelVO> voList = ExcelHandler.importExcel(multipartFile, BookLabelVO.class, null);

        if (CollectionUtils.isEmpty(voList))
            throw new DescribeException("导入数据为空");

        List<String> isbnList = voList.stream()
                .map(BookLabelVO::getIsbn)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());

        List<BookLabelDto> labelDtoList = booksService.labelListByIsbnIn(isbnList);
        Map<String, List<BookLabelDto>> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(labelDtoList)) {
            map = labelDtoList.stream().collect(Collectors.groupingBy(BookLabelDto::getIsbn));
        }

        // 表格头部列的数据
        List<List<String>> headList = new ArrayList<>();
        // 表格第一列默认是门店名称
        headList.add(Collections.singletonList("书号"));
        headList.add(Collections.singletonList("分类id"));
        headList.add(Collections.singletonList("分类名称"));
        // 表格内的数据
        List<List<Object>> dataList = new ArrayList<>();

        for (BookLabelVO bookLabelVO : voList) {
            List<Object> data = new ArrayList<>();
            String isbn = bookLabelVO.getIsbn();
            if (StringUtils.isNotBlank(isbn)) {
                data.add(isbn);
                List<BookLabelDto> list = map.get(isbn);
                if (CollectionUtils.isNotEmpty(list)) {
                    BookLabelDto labelDto = list.get(0);
                    data.add(labelDto.getBookLabelId());
                    data.add(labelDto.getBookLabelName());
                } else {
                    data.add("");
                    data.add("");
                }
            } else {
                data.add("");
                data.add("");
                data.add("");
            }
            dataList.add(data);
        }

        String fileName = "书单分类补充";
        EasyExcel.write(ExcelHandler.getOutputStream(fileName, response))
                // 设置单元格样式
                .registerWriteHandler(ExcelHandler.getCellStyleStrategy())
                .head(headList)
                .sheet("书单分类补充")
                .doWrite(dataList);
    }

    @ApiOperation(value = "给总部和门店书籍补充分类")
    @PostMapping(value = "/makeupBookAndStoreBookLabel", produces = "application/json; charset=UTF-8")
    public void makeupBookAndStoreBookLabel(
            @ApiParam(value = "书籍分类数据excel") @RequestPart(value = "books") MultipartFile multipartFile
    ) throws Exception {
        List<BookLabelVO> voList = ExcelHandler.importExcel(multipartFile, BookLabelVO.class, null);

        if (CollectionUtils.isEmpty(voList))
            throw new DescribeException("导入数据为空");

        Map<String, Long> bookLabelMap = BooksUtil.getBookLabelMap();
        for (BookLabelVO bookLabelVO : voList) {
            String labelName = bookLabelVO.getLabelName();
            Long labelId = bookLabelMap.get(labelName);
            bookLabelVO.setLabelId(labelId);
        }

        booksService.dbUpdateLabelInfoByIsbn(voList);
        storeBooksService.dbUpdateLabelInfoByIsbn(voList);

    }

}
